<?php

/**
 * Klasa sprawdzająca czy podana linijka NMEA ma poprawną checksumę
 *
 * @category	Core
 * @package		Core_Validate
 * @copyright	Copyright (c) 2008 Kuśmierz Adam
 */

class Core_Validate_NMEA extends Zend_Validate_Abstract
{
	const WRONGCHECKSUM = 'ChecksumIsWrong';
	
	/**
	 * @var array
	*/
	protected $_messageTemplates = array(
		self::WRONGCHECKSUM => 'Given checksum is wrong'
	);
		
	/**
	 * Defined by Zend_Validate_Interface
	 *
	 * Returns true if and only if the line has valid checksum
	 *
	 * @param  string|array $value
	 * @return boolean
	 */
	public function isValid($value)
	{
		if (is_array($value)) {
			$valid = true;
			foreach ($value as $v)
				if (!$this->isValid($v)) {
					$valid = false;
					break;
				}
			if ($valid)
				return true;
		} else {
			$value = (string) $value;
			$value = trim($value);
			$this->_setValue($value);
			
			$checksum = 0;
			preg_match('#^\$([^*]+)\*([0-9a-f]{2})$#i', $value, $match);
			
			if (count($match) === 3) {
				foreach (str_split($match[1]) as $char)
					$checksum ^= ord($char);
				if (strtolower($match[2]) === dechex($checksum >> 4) . dechex($checksum & 0xf))
					return true;
			}
		}
		$this->_error(self::WRONGCHECKSUM);
		return false;
	}
}